package com.yuan.member.service.impl;


import cn.common.constant.CacheConstant;
import cn.common.constant.SmsConstant;
import cn.common.enums.UserStatusEnum;
import cn.common.exception.BusinessException;

import cn.common.result.Response;
import cn.common.utils.JwtUtils;
import cn.common.utils.PasswordHelper;
import cn.common.utils.RandomUtil;

import cn.common.utils.UserContextUtils;
import cn.model.Balance;
import cn.model.Member;
import cn.model.SysConfig;
import cn.vo.CodeVo;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.xiaoleilu.hutool.collection.CollUtil;
import com.yuan.common.redis.constant.CacheConstants;
import com.yuan.common.redis.service.RedisRepository;
import com.yuan.member.mapper.BalanceMapper;
import com.yuan.member.mapper.MemberMapper;
import com.yuan.member.mapper.SysConfigMapper;
import com.yuan.member.producer.RabbitMqProducer;
import com.yuan.member.service.MemberService;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.logging.log4j.util.Strings;
import org.assertj.core.util.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;


@Slf4j
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private RabbitMqProducer rabbitMqProducer;
    @Autowired
    private RedisRepository redisRepository;

    @Autowired
    SysConfigMapper sysConfigMapper;
    @Autowired
    private BalanceMapper balanceMapper;
    @Override
    public boolean register(Member member, String code) {
        //1.验证身份类型
        //2.账号是否异常
        String phone = member.getPhone();
        if(phone.length() <11){
            throw new BusinessException("请输入有效的号码");
        }
        //3.账号是否注册
        QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone",phone);
        Member member1 = memberMapper.selectOne(queryWrapper);
        if(member1 != null){
            throw new BusinessException("账号已存在");
        }
        //4.是否有邀请码
        if(Strings.isNotBlank(member.getWelCode())){
            //判断邀请码是否存在
            QueryWrapper<Member> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("wel_code",member.getWelCode());
            Member code_member = memberMapper.selectOne(queryWrapper1);
            if(code_member != null){
                throw new BusinessException("邀请码不存在");
            }
           //设置邀请人的id
            member.setWelMember(member.getId());
        }
        String welCode = RandomUtil.genWelRandomNum();
        //生成邀请码
        QueryWrapper<Member> queryWel = new QueryWrapper<>();
        queryWel.eq("wel_code",welCode);
        boolean is_wel_code = memberMapper.exists(queryWel);
        if(is_wel_code){ //判断邀请码是否存在
            welCode = RandomUtil.genWelRandomNum();
        }
        //设置密钥涵
        String salt = UUID.randomUUID().toString().replaceAll("-", "");
        member.setPassword(PasswordHelper.encryString(member.getPassword(), salt));
        member.setSalt(salt);
        member.setWelCode(welCode);
        String uuid = RandomUtil.genUuid();
        QueryWrapper<Member> queryUuid = new QueryWrapper<>();
        queryUuid.eq("uuid",uuid);
        boolean is_uuid = memberMapper.exists(queryUuid);
        if(is_uuid){ //判断是否存在
            uuid = RandomUtil.genUuid();
        }
        member.setUuid(uuid);
        member.setUserStatus(UserStatusEnum.NORMAL.getStatus());
        //memberMapper.insert(member);member.getId()
        rabbitMqProducer.putRegister("test123321");
        rabbitMqProducer.putWalletPool("2222233333");
        //发送消息
        return Boolean.TRUE;
    }

    @Override
    public Map<String, Object> memberLogin(String phone, String password, String code) {
        log.info("用户信息{},{},{}",phone,password,code);
        //1.查询账号是否存在
          if(StringUtils.isAnyBlank(phone,password,code)){
              throw new BusinessException("用户/密码必须填写");
          }
          QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
          queryWrapper.eq("phone",phone);
          Member member = memberMapper.selectOne(queryWrapper);
          if(member == null){
              throw new BusinessException("用户名不存在");
          }
        //2.密码是否正确
        String pass =  PasswordHelper.encryString(password, member.getSalt());
        log.info("密码{},{}",pass,password);
          if(!Objects.equals(pass, member.getPassword())){
              throw new BusinessException("密码错误");
          }
        //3.是否异常
        if(Objects.equals(member.getUserStatus(), UserStatusEnum.UNNORMAL.getStatus())){
            throw new BusinessException("账号异常");
        }
        String token =  JwtUtils.generateToken(member.getId());
        Map<String, Object> tokens =  new HashMap<>();
        tokens.put("token",token);
        tokens.put("expiration",JwtUtils.EXPIRATION_TIME/1000);
        log.info("token信息{}",tokens);
        redisRepository.setExpire(CacheConstant.LOGIN_TOKEN_KEY + member.getId(), token, JwtUtils.EXPIRATION_TIME/1000);
        return tokens;
    }

    @Override
    public Map<String, Object> wechatLogin(String code) {


       SysConfig sysConfig = sysConfigMapper.selectByParamKey("阿里云AK");
        log.info("查询信息 {}",sysConfig);
       System.out.println(sysConfig);
//        String accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
//                "?appid=" + appid +
//                "&secret=" + appsecret +
//                "&code=" + code +
//                "&grant_type=authorization_code";
//        HttpClient httpClient = HttpClients.createDefault();
//        HttpGet httpGet = new HttpGet(accessTokenUrl);
        return null;
    }

    @SentinelResource(value = "buy",blockHandler = "ProductHandler")
    @Override
    public String getProduct(Integer id) {
        return "用户:"+id;
    }

    @Override
    public boolean checkSmsCode(String phone, String code, SmsConstant.Sms_Type type) {
        if(Strings.isBlank(phone) || Strings.isBlank(code)){
            throw new BusinessException("验证码为空");
        }
        String codeValue = redisRepository.get( CacheConstants.DEFAULT_CODE_KEY + phone +"-"+type);
        if(Strings.isBlank(codeValue)){
            throw new BusinessException("验证码已失效");
        }
        if(!code.equals(codeValue)){
            throw new BusinessException("验证码错误");
        }
        return true;
    }

    public String ProductHandler(Integer id,BlockException e){
        return "限流处理:"+id;
    }


    public Member getMember(){
        String userId = UserContextUtils.getCurrentUserId();
        return memberMapper.selectById(userId);
    }

    public List<Balance> queryBalance(String symbol){
        String userId = UserContextUtils.getCurrentUserId();
        System.out.println("用户id:"+userId);
        LambdaQueryWrapper<Balance> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         if(Strings.isNotBlank(symbol)){
             lambdaQueryWrapper.eq(Balance::getCurrency,symbol);
         }
        lambdaQueryWrapper.eq(Balance::getUserId,userId);
        List<Balance> balanceList =  balanceMapper.selectList(lambdaQueryWrapper);
        if(CollUtil.isNotEmpty(balanceList)){
           return balanceList;
        }else {
            //List<String> currencys = Lists.newArrayList();
        }
         return null;
    }

    public CodeVo getCode(){
        String userId = UserContextUtils.getCurrentUserId();
        CodeVo codeVo = new CodeVo();
        Member member = memberMapper.selectById(userId);
        BeanUtils.copyProperties(member,codeVo);
        return codeVo;
    }

    public HashMap<String,Object> selectInviteRecord(){
        String userId = UserContextUtils.getCurrentUserId();
       Integer invitCount =  memberMapper.invitations(userId);
       HashMap<String,Object> hashMap =  new HashMap<>();
       hashMap.put("invitCount",invitCount);
        return hashMap;
    }
}
